import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_highlight/flutter_highlight.dart';
import 'package:flutter_markdown/flutter_markdown.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:note/common/tools.dart';
import 'package:note/widgets/showPhotoView.dart';
import 'package:get/get.dart';
import '../common/styles.dart';
import 'package:markdown/markdown.dart' as md;

//字体样式
class MdStyle {
  static MarkdownStyleSheet markdownStyleSheet = MarkdownStyleSheet(
    codeblockDecoration: const BoxDecoration(
      borderRadius: BorderRadius.all(Radius.circular(10)),
      color: Styles.codeBGColor, // 底色设置代码块
    ),
    codeblockPadding: const EdgeInsets.all(10),
    code: TextStyle(
      backgroundColor: Styles.codeBGColor.withOpacity(0.5),
      color: Styles.mainThemeColor,
      fontSize: 15,
      fontFamily: 'CodeFont',
      height: 1.3,
    ),
    checkbox: const TextStyle(fontSize: 10, height: 1),
    h1: Styles.textStyleBold(35),
    h2: Styles.textStyleMedium(30),
    h3: Styles.textStyleMedium(25),
    h4: Styles.textStyleMedium(20),
    p: Styles.textStyleNormal(15),
    pPadding: const EdgeInsets.only(bottom: 10),
    listBullet: Styles.textStyleBold(15),
    em: Styles.textStyleNormal(15),
  );

  static Map<String, MarkdownElementBuilder> builders = {
    'code': CodeElementBuilder()
  };

  static void onTapLink(String text, String? href, String title) {
    if (href == null) return;
    Tools.launchURL(href);
  }

  static Widget imageBuilder(Uri uri, String? title, String? alt) {
    return GestureDetector(
      onTap: () {
        Get.to(ShowPhotoView(
          uri.toString(),
          isNetImg: true,
        ));
        // launchUrl(uri);
      },
      child: Image.network(uri.toString()),
    );
  }

  static Widget checkBox(bool yes) {
    return Icon(
      yes ? Icons.check_box : Icons.check_box_outline_blank,
      color: Colors.blue,
      size: 12,
    );
  }
}

class MyMarkDown extends StatelessWidget {
  final String data;
  final ScrollController? scrollController;

  const MyMarkDown({super.key, required this.data, this.scrollController});

  @override
  Widget build(BuildContext context) {
    return Markdown(
      data: data,
      controller: scrollController ?? ScrollController(),
      styleSheet: MdStyle.markdownStyleSheet,
      selectable: true,
      onTapLink: MdStyle.onTapLink,
      imageBuilder: MdStyle.imageBuilder,
      checkboxBuilder: MdStyle.checkBox,
      // builders: MdStyle.builders,
    );
  }
}

class MyMarkDownBody extends StatelessWidget {
  final String data;
  final EdgeInsetsGeometry? padding;

  const MyMarkDownBody({super.key, required this.data, this.padding});

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: padding ?? const EdgeInsets.all(16.0),
      child: SingleChildScrollView(
        controller: PrimaryScrollController.of(context),
        child: MarkdownBody(
          data: data,
          styleSheet: MdStyle.markdownStyleSheet,
          selectable: true,
          fitContent: false, //代码块横向填充
          onTapLink: MdStyle.onTapLink,
          imageBuilder: MdStyle.imageBuilder,
          checkboxBuilder: MdStyle.checkBox,
          // builders: MdStyle.builders,
        ),
      ),
    );
  }
}

class CodeHeightLightView extends StatelessWidget {
  final String content;

  final String lang;

  const CodeHeightLightView(
      {super.key, required this.content, required this.lang});

  @override
  Widget build(BuildContext context) {
    return ClipRRect(
      borderRadius: const BorderRadius.all(Radius.circular(10)),
      child: HighlightView(
        content,
        language: lang,
        theme: mdTheme,
        padding: const EdgeInsets.all(8),
        textStyle: const TextStyle(fontSize: 15),
      ),
    );
  }
}

class CodeElementBuilder extends MarkdownElementBuilder {
  @override
  Widget? visitElementAfter(md.Element element, TextStyle? preferredStyle) {
    var language = '';
    if (element.attributes['class'] != null) {
      String lg = element.attributes['class'] as String;
      language = lg.substring(9);
    }
    return GestureDetector(
      onTap: () {
        Clipboard.setData(ClipboardData(text: element.textContent));
        Toasts.showToast('代码已复制', gravity: ToastGravity.BOTTOM);
      },
      child: CodeHeightLightView(
        content: element.textContent,
        lang: language,
      ),
    );
  }
}

const mdTheme = {
  'root': TextStyle(
      color: Color(0xff333333), backgroundColor: Styles.backgroundColor),
  'comment': TextStyle(color: Color(0xff999988), fontStyle: FontStyle.italic),
  'quote': TextStyle(color: Color(0xff999988), fontStyle: FontStyle.italic),
  'keyword': TextStyle(color: Color(0xff333333), fontWeight: FontWeight.bold),
  'selector-tag':
      TextStyle(color: Color(0xff333333), fontWeight: FontWeight.bold),
  'subst': TextStyle(color: Color(0xff333333), fontWeight: FontWeight.normal),
  'number': TextStyle(color: Color(0xff008080)),
  'literal': TextStyle(color: Color(0xff008080)),
  'variable': TextStyle(color: Color(0xff008080)),
  'template-variable': TextStyle(color: Color(0xff008080)),
  'string': TextStyle(color: Color(0xffdd1144)),
  'doctag': TextStyle(color: Color(0xffdd1144)),
  'title': TextStyle(color: Color(0xff990000), fontWeight: FontWeight.bold),
  'section': TextStyle(color: Color(0xff990000), fontWeight: FontWeight.bold),
  'selector-id':
      TextStyle(color: Color(0xff990000), fontWeight: FontWeight.bold),
  'type': TextStyle(color: Color(0xff445588), fontWeight: FontWeight.bold),
  'tag': TextStyle(color: Color(0xff000080), fontWeight: FontWeight.normal),
  'name': TextStyle(color: Color(0xff000080), fontWeight: FontWeight.normal),
  'attribute':
      TextStyle(color: Color(0xff000080), fontWeight: FontWeight.normal),
  'regexp': TextStyle(color: Color(0xff009926)),
  'link': TextStyle(color: Color(0xff009926)),
  'symbol': TextStyle(color: Color(0xff990073)),
  'bullet': TextStyle(color: Color(0xff990073)),
  'built_in': TextStyle(color: Color(0xff0086b3)),
  'builtin-name': TextStyle(color: Color(0xff0086b3)),
  'meta': TextStyle(color: Color(0xff999999), fontWeight: FontWeight.bold),
  'deletion': TextStyle(backgroundColor: Color(0xffffdddd)),
  'addition': TextStyle(backgroundColor: Color(0xffddffdd)),
  'emphasis': TextStyle(fontStyle: FontStyle.italic),
  'strong': TextStyle(fontWeight: FontWeight.bold),
};
